package cn.sdut.training.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import cn.sdut.training.cfg.Configuration;
import cn.sdut.training.dao.BaseDao;
import cn.sdut.training.utils.HqlHelper;
import cn.sdut.training.utils.PageView;

@SuppressWarnings("unchecked")
public abstract class BaseDaoImpl<T> implements BaseDao<T>{


	private SessionFactory sessionFactory;

	private Class clazz;
	public BaseDaoImpl() {
		ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
		clazz = (Class) type.getActualTypeArguments()[0];
	}

	@Override
	public void batchHandleByHQL(String hql, Serializable... serializables) {
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		for(int i=0;i<serializables.length;i++){
			query.setParameter(i, serializables[i]);
		}
		query.executeUpdate();
	}

	@Override
	public void deleteEntity(T t) {
		sessionFactory.getCurrentSession().delete(t);
	}

	
	@Override
	public List<T> findEntityByHQL(String hql, Serializable... serializables) {
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		for(int i=0;i<serializables.length;i++){
			query.setParameter(i, serializables[i]);
		}
		return query.list();
	}

	@Override
	public T getEntity(Long id) {
		return (T) sessionFactory.getCurrentSession().get(clazz, id);
	}

	@Override
	public T loadEntity(Long id) {
		return (T) sessionFactory.getCurrentSession().load(clazz, id);
	}

	@Override
	public void saveEntity(T t) {
		sessionFactory.getCurrentSession().save(t);
	}

	@Override
	public void saveOrUpdateEntity(T t) {
		sessionFactory.getCurrentSession().saveOrUpdate(t);
	}

	@Override
	public void updateEntity(T t) {
		sessionFactory.getCurrentSession().update(t);
	}
	
	@Resource
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Override
	public Object uniqueResult(String hql, Serializable... serializables) {
		Query query = sessionFactory.getCurrentSession().createQuery(hql);
		for(int i=0;i<serializables.length;i++){
			query.setParameter(i, serializables[i]);
		}
		return query.uniqueResult();
	}
	
	public PageView getPageView(HqlHelper hqlHelper, int pageNum) {
		int pageSize = Configuration.getPageSize();
		List<Object> paramList = hqlHelper.getParamList();

		// 查询总记录数
		Query countQuery = getSession().createQuery(hqlHelper.getQueryCountHql());
		for (int i = 0; i < paramList.size(); i++) { // 设置参数
			countQuery.setParameter(i, paramList.get(i));
		}
		int recordCount = ((Number) countQuery.uniqueResult()).intValue(); // 查询

		// 查询数据列表
		Query listQuery = getSession().createQuery(hqlHelper.getQueryListHql());
		for (int i = 0; i < paramList.size(); i++) { // 设置参数
			listQuery.setParameter(i, paramList.get(i));
		}
		listQuery.setFirstResult((pageNum - 1) * pageSize);
		listQuery.setMaxResults(pageSize);
		List recordList = listQuery.list(); // 查询

		return new PageView(pageNum, pageSize, recordCount, recordList);
	}

	/**
	 * 获取当前可用的Session
	 * @return
	 */
	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}
	
}
